package com.bangcommunity.bbframe.monitor.logger;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.rolling.RollingFileAppender;
import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
import org.slf4j.ILoggerFactory;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author tanghc
 * @date 18/1/29
 */
public abstract class LogbackFacility {

    private static Logger createLogger(String mLoggerName, String fileName, String pattern) {
        if (null == pattern) {
            pattern = "%msg%n";
        }
        Map<String, Logger> allLoggers = getAllLoggers();
        if (null != allLoggers && null != allLoggers.get(mLoggerName)) {
            return allLoggers.get(mLoggerName);
        }
        ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory();
        if (loggerFactory instanceof LoggerContext) {
            LoggerContext loggerContext = (LoggerContext) loggerFactory;
            Logger logger = loggerContext.getLogger(mLoggerName);

            RollingFileAppender<ILoggingEvent> appender = new RollingFileAppender<>();
            String filePath = LogFileAccessor.getFilePath(fileName);
            appender.setFile(filePath);
            PatternLayoutEncoder encoder = new PatternLayoutEncoder();
            encoder.setPattern(pattern);
            encoder.setContext(loggerContext);
            encoder.start();
            // RollingPolicy
            TimeBasedRollingPolicy<ILoggingEvent> rollingPolicy = new TimeBasedRollingPolicy<>();
            rollingPolicy.setFileNamePattern(filePath + ".%d{yyyyMMdd}");
            rollingPolicy.setContext(loggerContext);
            rollingPolicy.setParent(appender);
            rollingPolicy.setMaxHistory(30);// 最多保留30份
            rollingPolicy.start();
            // assemble appender
            appender.setEncoder(encoder);
            appender.setRollingPolicy(rollingPolicy);
            appender.setContext(loggerContext);
            appender.start();

            logger.addAppender(appender);
            logger.setLevel(Level.INFO);
            logger.setAdditive(false);
            return logger;
        }
        return null;
    }

    public static Logger createLogger(MLoggerName mLoggerName, String mkey) {
        String pattern = "%msg%n";
        switch (mLoggerName) {
        case mlog_stat:
            pattern = "%msg%n";
            break;
        case mlog_trace:
            pattern = "[%d{yyyy-MM-dd HH:mm:ss.SSS}][%level] [%thread] %logger{20} [%file:%line] - %msg%n";
            break;
        }
        return createLogger(mLoggerName.name(), mLoggerName.getLoggerFileName(mkey), pattern);
    }

    public static Map<String, Logger> getAllLoggers() {
        Map<String, Logger> allLoggers = new HashMap<>();
        try {
            ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory();
            if (loggerFactory instanceof LoggerContext) {
                LoggerContext loggerContext = (LoggerContext) loggerFactory;
                List<Logger> loggerList = loggerContext.getLoggerList();
                if (loggerList != null && loggerList.size() > 0) {
                    for (Logger logger : loggerList) {
                        allLoggers.put(logger.getName(), logger);
                    }
                }
            }
        } catch (Throwable ignore) {
        }
        return allLoggers;
    }

}
